﻿/* Copyright 2010 Imaginary Development. All rights reserved*/

function CalculateDistance(galaxy1, galaxy2, system1, system2, position1, position2) {
    if (!galaxy1 || !galaxy2 || galaxy1 < 0 || galaxy2 < 0)
        throw  "Invalid galaxy";
    if (galaxy1 != galaxy2) {
        return 20000 * Math.abs(galaxy1 - galaxy2);
    }
    if (!system1 || !system2 || system1 < 0 || system2 < 0)
        throw  "Invalid system";
    if (system1 != system2) {
        return 2700 + 95 * Math.abs(system1 - system2);
    }
    if (position1 != position2) {
        return 1000 + 5 * Math.abs(position1 - position2);
    }
    return 5;
}
function ParseLocation(element) {
    function Location() {
        this.Galaxy = null;
        this.System = null;
        this.Position = null;
        this.IsMoon = null;
    };
    //var text = element.text();
    var result = new Location();
    var val = element.val();
    var re = new RegExp('\\D*([0-9]+)\\D?([0-9]+)?\\D?([0-9]+)?');
    var m=re.exec(element.val());
    if (m == null)
        return result;
    if (m.length ==2) {
        result.Galaxy = m[1];
        return result;
    }
    if (m.length == 3) {
        result.Galaxy = m[1];
        result.System=m[2];
        return result;
    }
    if (m.length == 4) {
        result.Galaxy = m[1];
        result.System = m[2];
        result.Position = m[3];
    }
    return result;
}

function ParseUILocation(table, subTextBase) {
    var location = ParseLocation($('input#'+subTextBase+'Text', table));

    var subTextInput=$('input#'+subTextBase + 'Galaxy', table)
    if (location.Galaxy) {
        subTextInput.val(location.Galaxy);
    } else {  //pull in if parse did not
        location.Galaxy = parseInt(subTextInput.val(), 10);
    }

    subTextInput = $('input#' + subTextBase + 'System', table);
    if (location.System) {
        subTextInput.val(location.System);
    } else {  //pull in if parse did not
        location.System =  parseInt(subTextInput.val(),10);
    }

    subTextInput = $('input#' + subTextBase + 'Position', table);
    if (location.Position) {

       subTextInput.val(location.System);
    } else { //pull in if parse did not

       location.Position =parseInt( subTextInput.val(),10);
    }
    return location;
}
function CalculateAccountDistance() {
   
    var table=$('table#distanceTable tbody');
    //parse text if needed for start
    var location1 = ParseUILocation( table,'Start');
    //parse text if needed for destination
    var location2=ParseUILocation(table,'End');
    //do calculation
    var distance=CalculateDistance(location1.Galaxy,location2.Galaxy,location1.System,
        location2.System,location1.Position,location2.position);
    //display result
    $('input#Distance', table).val(distance);
}
   

function CalculateResources() {
    //Final balance is (attackerlosses-defenderlosses)+harvest+plunder
    //Profit is harvest+plunder-attacker losses

    var balanceRow = $('table#balance tr#AttackerBalance');
    var attackerRow = $('table#balance tr#Attacker');
    var balance=new Resource();
    var profit = new Resource();
    
    function AddRowValues(sign, row, selectorBase,destination) {
        destination.Ore += sign * TextIntOrZero($(selectorBase + 'ore', row));
        destination.Crystal += sign * TextIntOrZero($(selectorBase + 'crystal', row));
        destination.Hydro += sign * TextIntOrZero($(selectorBase + 'hydrogen',row));
    };

    AddRowValues(-1, attackerRow, 'td.', profit);
    AddRowValues(1, balanceRow, 'td.', balance);


    var resourcesTable = $('table#resources tbody');

    var attackerHydro = $('input#HydroSpent', resourcesTable);
    profit.Hydro -= InputOrZero(attackerHydro);
    balance.Hydro -= InputOrZero(attackerHydro);
    
    var plunderRow=$('tr#PlunderRow',resourcesTable);
    var harvestRow=$('tr#HarvestRow',resourcesTable);
    balance.Ore += InputOrZero($('input#OrePlunder', plunderRow)) + InputOrZero($('input#OreHarvest', harvestRow));
    balance.Crystal += InputOrZero($('input#CrystalPlunder', plunderRow)) + InputOrZero($('input#CrystalHarvest', harvestRow));
    balance.Hydro += InputOrZero($('input#HydroPlunder', plunderRow));
    profit.Ore += InputOrZero($('input#OrePlunder', plunderRow)) + InputOrZero($('input#OreHarvest', harvestRow));
    profit.Crystal += InputOrZero($('input#CrystalPlunder', plunderRow)) + InputOrZero($('input#CrystalHarvest', harvestRow));
    profit.Hydro += InputOrZero($('input#HydroPlunder', plunderRow));

    var profitRow = $('tr#ProfitRow', resourcesTable);
    var finalBalanceRow = $('tr#FinalBalanceRow', resourcesTable);

    $('td#ProfitOre', profitRow).text(profit.Ore);
    $('td#ProfitCrystal', profitRow).text(profit.Crystal);
    $('td#ProfitHydro', profitRow).text(profit.Hydro);

    $('td#FinalOre', finalBalanceRow).text(balance.Ore);
    $('td#FinalCrystal', finalBalanceRow).text(balance.Crystal);
    $('td#FinalHydrogen', finalBalanceRow).text(balance.Hydro);
    
}
function TextIntOrZero(element) {
    var value = parseInt(element.text(),10);
    if (value != null && isNaN(value) == false && isFinite(value))
        return value;
    return 0;
}
function DisplayBalance(attackerResources, defenderResources, balance) {
    $('div#status').text('Balance Calculating');
    var balanceBody = $("table#balance tbody");
    var trFunc = function(player, resources) {
        var row = $('tr#' + player, balanceBody);
        $('td.ore',row).text(resources.Ore);
        $('td.crystal',row).text(resources.Crystal);
        $('td.hydrogen',row).text(resources.Hydro);
        if (resources.OreDebris != undefined) {
            $('td.oreDebris',row).text(resources.OreDebris);
            $('td.crystalDebris',row).text(resources.CrystalDebris);
        }
    };
    trFunc("Attacker", attackerResources);
    trFunc("Defender", defenderResources);
    trFunc("AttackerBalance", balance);
    var total=attackerResources.GetSum(defenderResources);
    trFunc("Total", total);
    var recyclers=(total.OreDebris+total.CrystalDebris)/20000;
    $('tr#Recyclers td#BalanceRecyclers', balanceBody).text(recyclers);
    $('div#status').text('Balance Calculated');
}

function Resource() {
    this.Ore = 0;
    this.Crystal = 0;
    this.Hydro = 0;
    this.OreDebris = 0;
    this.CrystalDebris = 0;
    this.Add = function(ore, crystal, hydro, makesDebris) {
        this.Ore += ore;
        this.Crystal += crystal;
        this.Hydro += hydro;
        if (makesDebris === true) {
            this.OreDebris += ore * .3;
            this.CrystalDebris += crystal * .3;
        }
    };
    this.GetSum = function(resource) {
        var result = new Resource();
        result.Ore = this.Ore + resource.Ore;
        result.Crystal = this.Crystal + resource.Crystal;
        result.Hydro = this.Hydro + resource.Hydro;
        result.OreDebris = this.OreDebris + resource.OreDebris;
        result.CrystalDebris = this.CrystalDebris + resource.CrystalDebris;
        return result;
    }
    this.Subtract = function(resource) {
        return { Ore: this.Ore - resource.Ore, Crystal: this.Crystal - resource.Crystal, Hydro: this.Hydro - resource.Hydro };
    };
}

function CalculateBalance() {
    var resourcesAttacker = new Resource();
    var resourcesDefender = new Resource();

    $('tr[debris]').each(function(index, tr) {
        var type = $('td:first', tr).text().replace(" ", "");

        var attackerCount = InputOrZero($('td input#' + type + 'A', tr));
        var defenderCount = InputOrZero($('td input#' + type + 'D', tr));
        if (attackerCount > 0) {
            TotalLost(tr, attackerCount, resourcesAttacker);
        }
        if (defenderCount > 0) {
            TotalLost(tr, defenderCount, resourcesDefender);
        }

    });
    DisplayBalance(resourcesAttacker, resourcesDefender, resourcesDefender.Subtract(resourcesAttacker));
}
function InputOrZero(inputOrNull) {
    if (inputOrNull == null || inputOrNull.val()=="")
        return 0;
        return parseInt( inputOrNull.val(),10);
}
function TotalLost(tr, count, resources) {
    resources.Add($(tr).attr('ore') * count, $(tr).attr('crystal') * count, $(tr).attr('hydrogen') * count, $(tr).attr('debris') == 1);
}